Looking at wider covid impacts data weekly variability - related to
2018/19 baseline
revised version - now extracting all Scotland more easily.
library("tidyverse")
library("janitor")
library("lubridate")
hb_codes <- read_csv("health_board_codes.csv")
Rows: 18 Columns: 5── Column specification ──────────────────────────────────────────────────────────────────
Delimiter: ","
chr (3): HB, HBName, Country
dbl (2): HBDateEnacted, HBDateArchived
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
hb_codes <- clean_names(hb_codes)
load in datafiles
weekly_admissions_spec <- read_csv("Covid admissions by health board and speciality.csv")
Rows: 55233 Columns: 11── Column specification ──────────────────────────────────────────────────────────────────
Delimiter: ","
chr (6): HB, HBQF, AdmissionType, AdmissionTypeQF, Specialty, SpecialtyQF
dbl (5): _id, WeekEnding, NumberAdmissions, Average20182019, PercentVariation
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
weekly_admissions_spec <- clean_names(weekly_admissions_spec)
weekly_admissions_dep <- read_csv("Covid admissions by health board and deprivation.csv")
Rows: 30370 Columns: 10── Column specification ──────────────────────────────────────────────────────────────────
Delimiter: ","
chr (4): HB, HBQF, AdmissionType, AdmissionTypeQF
dbl (6): _id, WeekEnding, SIMDQuintile, NumberAdmissions, Average20182019, PercentVari...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
weekly_admissions_dep <- clean_names(weekly_admissions_dep)
weekly_admissions_demog <- read_csv("Covid admissions by health board, age and sex.csv")
Rows: 61951 Columns: 13── Column specification ──────────────────────────────────────────────────────────────────
Delimiter: ","
chr (8): HB, HBQF, AgeGroup, AgeGroupQF, Sex, SexQF, AdmissionType, AdmissionTypeQF
dbl (5): _id, WeekEnding, NumberAdmissions, Average20182019, PercentVariation
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
weekly_admissions_demog <- clean_names(weekly_admissions_demog)
data cleaning note probably more cleaning needed before we finalise I
changed the spelling but it turns out both spellings are correct!
weekly_admissions_spec <- weekly_admissions_spec %>%
rename("speciality"= "specialty") %>%
rename("speciality_qf"= "specialty_qf")
merge hbnames into datafiles
weekly_admissions_spec <- left_join(weekly_admissions_spec,hb_codes)
Joining, by = "hb"
weekly_admissions_demog <- left_join(weekly_admissions_demog,hb_codes)
Joining, by = "hb"
weekly_admissions_dep <- left_join(weekly_admissions_dep,hb_codes)
Joining, by = "hb"
do the analysis needed for identifying qinter and ‘crisis’
weekly_admissions_spec <- weekly_admissions_spec %>%
mutate(year = as.integer(str_sub(week_ending,1,4))) %>%
mutate(month = as.integer(str_sub(week_ending,5,6))) %>%
mutate(day = as.integer(str_sub(week_ending,7,8))) %>%
mutate(wdate = ymd(week_ending)) %>%
# identify "All Scotland" data
mutate(hb_name = ifelse(hb=="S92000003","All Scotland",hb_name)) %>%
mutate(hb_name = ifelse(is.na(hb_name),"NHS Region Unknown",hb_name)) %>%
mutate(iswinter = ifelse(month %in% c(4,5,6,7,8,9),FALSE,TRUE)) %>%
mutate(above_thresh = ifelse(percent_variation>0,7,0))
weekly_admissions_demog <- weekly_admissions_demog %>%
mutate(year = as.integer(str_sub(week_ending,1,4))) %>%
mutate(month = as.integer(str_sub(week_ending,5,6))) %>%
mutate(day = as.integer(str_sub(week_ending,7,8))) %>%
mutate(wdate = ymd(week_ending)) %>%
# identify "All Scotland" data
mutate(hb_name = ifelse(hb=="S92000003","All Scotland",hb_name)) %>%
mutate(hb_name = ifelse(is.na(hb_name),"NHS Region Unknown",hb_name)) %>%
mutate(iswinter = ifelse(month %in% c(4,5,6,7,8,9),FALSE,TRUE)) %>%
mutate(above_thresh = ifelse(percent_variation>0,7,0))
weekly_admissions_dep <- weekly_admissions_dep %>%
mutate(year = as.integer(str_sub(week_ending,1,4))) %>%
mutate(month = as.integer(str_sub(week_ending,5,6))) %>%
mutate(day = as.integer(str_sub(week_ending,7,8))) %>%
mutate(wdate = ymd(week_ending)) %>%
# identify "All Scotland" data
mutate(hb_name = ifelse(hb=="S92000003","All Scotland",hb_name)) %>%
mutate(hb_name = ifelse(is.na(hb_name),"NHS Region Unknown",hb_name)) %>%
mutate(iswinter = ifelse(month %in% c(4,5,6,7,8,9),FALSE,TRUE)) %>%
mutate(above_thresh = ifelse(percent_variation>0,7,0))
take a look at what is in each dataset
weekly_admissions_spec %>%
distinct(hb_name)
14 health boards plus ‘all scotland’ and an NA - need to work out
what to do with this
weekly_admissions_spec %>%
distinct(admission_type)
Data neatly divided into emergency and planned
weekly_admissions_spec %>%
distinct(speciality)
note that some groupings are also combined. need to take a closer
look at what these mean.
weekly_admissions_demog %>%
distinct(age_group)
7 age groups and “all ages”
weekly_admissions_demog %>%
distinct(sex)
just male - female and all
weekly_admissions_dep %>%
distinct(simd_quintile)
note there is no ‘all’ category in this dataset
plot total admissions - you should get the same overall trends from
each dataset
weekly_admissions_demog %>%
filter(age_group == "All ages") %>%
filter(sex =="All") %>%
filter(admission_type == "All") %>%
filter(hb_name =="All Scotland") %>%
ggplot() +
aes(x=wdate, y = number_admissions) +
geom_line(colour='red')

weekly_admissions_spec %>%
filter(speciality == "All") %>%
filter(admission_type == "All") %>%
filter(hb_name =="All Scotland") %>%
ggplot() +
aes(x=wdate, y = number_admissions) +
geom_line(colour='red')

same graph as above!
weekly hospital admissions hover around 14000 per week expect 168,000
per quarter?
pre=pandemic hospital admissions hovered around 15500 per week expect
186,000 per quarter
weekly_admissions_spec %>%
filter(speciality == "All") %>%
filter(admission_type == "All") %>%
filter(hb_name =="All Scotland") %>%
ggplot() +
aes(x=wdate, y = percent_variation) +
geom_line(colour='red')

Overall(all specialities, all admissions, all healthboards)
admissions are only at 90% of pre-pandemic levels
quick look at demographics
weekly_admissions_demog %>%
filter(sex == "All") %>%
filter(age_group != "All ages") %>%
filter(hb_name =="All Scotland") %>%
filter(admission_type == "All") %>%
ggplot() +
aes(x=wdate, y = number_admissions, color = age_group) +
geom_line() #+

#scale_colour_brewer(palette = "Set2")
age plot shows some variation between age groups.
quick look at sex differences
weekly_admissions_demog %>%
filter(sex != "All") %>%
filter(age_group == "All ages") %>%
filter(hb_name =="All Scotland") %>%
filter(admission_type == "All") %>%
ggplot() +
aes(x=wdate, y = percent_variation, color = sex) +
geom_line() #+

#scale_colour_brewer(palette = "Set2")
quick look at index of deprivation. 1 is most deprived and 5 is least
deprived
weekly_admissions_dep %>%
filter(admission_type == "All") %>%
filter(hb_name =="All Scotland") %>%
ggplot() +
aes(x=wdate, y = percent_variation, color = as.factor(simd_quintile)) +
geom_line()

something happening in 2022 - why is there divergence between 1 and
5?
look at admissions type
weekly_admissions_spec %>%
filter(admission_type != "All") %>%
filter(speciality=="All") %>%
filter(hb_name =="All Scotland") %>%
ggplot() +
aes(x=wdate, y = percent_variation, colour = admission_type) +
geom_line()

need to check what the ‘spike’ in planned at end of 2021 is related
to
quick look at specialities
weekly_admissions_spec %>%
filter(admission_type == "All") %>%
filter(speciality !="All") %>%
filter(hb_name =="All Scotland") %>%
ggplot() +
aes(x=wdate, y = percent_variation, colour=speciality) +
geom_line()

take a closer look at paediatrics
weekly_admissions_spec %>%
filter(admission_type == "All") %>%
filter(speciality !="All") %>%
filter(str_detect(speciality,"Paed")) %>%
filter(hb_name =="All Scotland") %>%
ggplot() +
aes(x=wdate, y = number_admissions, colour=speciality) +
geom_line()

weekly_admissions_spec %>%
filter(admission_type == "All") %>%
filter(speciality !="All") %>%
filter(str_detect(speciality,"Paed")) %>%
filter(hb_name =="All Scotland") %>%
ggplot() +
aes(x=wdate, y = percent_variation, colour=speciality) +
geom_line()

take a closer look at medical
weekly_admissions_spec %>%
filter(admission_type == "All") %>%
filter(speciality !="All") %>%
filter(str_detect(speciality,"Medical")) %>%
filter(hb_name =="All Scotland") %>%
ggplot() +
aes(x=wdate, y = percent_variation, colour=speciality) +
geom_line()

simpler plot of specialities
weekly_admissions_spec %>%
filter(admission_type == "Planned") %>%
filter(speciality !="Medical (incl. Cardiology & Cancer)") %>%
filter(!str_detect(speciality,"Paed")) %>%
filter(speciality !="All") %>%
filter(speciality !="Accident & Emergency") %>%
filter(hb_name =="All Scotland") %>%
ggplot() +
aes(x=wdate, y = percent_variation, colour=speciality) +
geom_line() +
scale_colour_brewer(palette = "Set1")

weekly_admissions_spec %>%
filter(admission_type == "Emergency") %>%
filter(speciality !="Medical (incl. Cardiology & Cancer)") %>%
filter(!str_detect(speciality,"Paed")) %>%
filter(speciality !="All") %>%
filter(speciality !="Accident & Emergency") %>%
filter(hb_name =="All Scotland") %>%
ggplot() +
aes(x=wdate, y = percent_variation, colour=speciality) +
geom_line() +
scale_colour_brewer(palette = "Set1")

boxplot for different specialities? some values greater than 8000% (i
have filtered them out ) indicates we need some more work on data
cleaning!
weekly_admissions_spec %>%
#filter(admission_type == "All") %>%
#filter(speciality!="All") %>%
#filter(hb_name =="NHS Region Unknown") %>%
#group_by(speciality) %>%
#need to take a good look at what these values are!
filter(percent_variation>500)
weekly_admissions_spec %>%
filter(admission_type == "All") %>%
filter(speciality!="All") %>%
group_by(speciality) %>%
#need to take a good look at what these values are!
filter(percent_variation<8000) %>%
ggplot()+
aes(x=speciality, y=percent_variation)+
geom_boxplot()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))

some specialities have faced higher admission levels than others.
Now look by health boards
all_admissions_byhb <- weekly_admissions %>%
filter(admission_type == "All") %>%
filter(speciality=="All") %>%
group_by(hb_name) %>%
summarise(mean_percnt_var = mean(percent_variation),
min_percnt_var = min(percent_variation),
max_percnt_var = max(percent_variation)
) %>%
#mutate(all_percent_variation = all_admissions/all_avg20182019)
arrange(desc(max_percnt_var))
all_admissions_byhb
weekly_admissions_spec %>%
filter(admission_type == "All") %>%
filter(speciality=="All") %>%
group_by(hb_name) %>%
ggplot()+
aes(x=wdate, y=percent_variation, colour = hb_name)+
geom_line()

weekly_admissions_spec %>%
filter(admission_type == "All") %>%
filter(speciality=="All") %>%
group_by(hb_name) %>%
ggplot()+
aes(x=hb_name, y=percent_variation)+
geom_boxplot()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))

for some health boards a significant number of admissions levels are
above the levels seen in 2018-19. could we parhaps try and use this as
an indicator?
Need to think more carefully about what the data in ‘region unknown’
means
weekly_admissions_spec %>%
filter(admission_type == "All") %>%
filter(speciality=="All") %>%
ggplot() +
aes(x=wdate, y=percent_variation, colour=hb_name) +
geom_line()+
facet_wrap(~hb_name)

How is NA calculated - still need to check??
weekly_admissions_spec %>%
filter(admission_type == "All") %>%
filter(speciality == "All") %>%
filter(hb_name != "All Scotland") %>%
ggplot() +
aes(x=wdate, y = number_admissions, colour = hb_name) +
geom_line()

admission values shows all health boards - health boards vary
massively in size and admission numbers but mostly same overall
pattern.
weekly_admissions_spec %>%
filter(admission_type == "All") %>%
filter(speciality=="Accident & Emergency") %>%
#take a good look at what these values are!
filter(percent_variation<8000) %>%
group_by(hb_name) %>%
ggplot()+
aes(x=hb_name, y=percent_variation)+
geom_boxplot() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

do only certain health boards have an A+E dept?
weekly_admissions_spec %>%
filter(admission_type == "Emergency") %>%
#filter(speciality=="Accident & Emergency") %>%
#take a good look at what these values are!
filter(percent_variation<8000) %>%
group_by(hb_name) %>%
ggplot()+
aes(x=hb_name, y=percent_variation)+
geom_boxplot() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

first attempt at a ‘crisis’ calculation
weekly_admissions %>%
filter(admission_type == "All") %>%
filter(speciality=="All") %>%
#filter(admission_type =="Emergency") %>%
#filter(speciality=="Accident & Emergency") %>%
#filter(year == 2020) %>%
filter(iswinter) %>%
group_by(hb_name) %>%
summarise(count_bad_days = sum(above_thresh),
count_days = n()*7,
pcnt_bad_days = 100*(sum(above_thresh)/(n()*7)),
mean_percentvar =mean(percent_variation)) %>%
ggplot() +
aes(x=hb_name, y=mean_percentvar) +
geom_col() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

weekly_admissions_spec %>%
filter(speciality=="All") %>%
filter(admission_type =="All") %>%
#filter(year == 2021) %>%
#filter(iswinter) %>%
group_by(hb_name) %>%
summarise(count_bad_days = sum(above_thresh),
count_days = n()*7,
pcnt_bad_days = 100*(sum(above_thresh)/(n()*7)),
mean_percentvar =mean(percent_variation)) %>%
ggplot() +
aes(x=hb_name, y=pcnt_bad_days) +
geom_col() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

weekly_admissions_spec %>%
filter(speciality=="All") %>%
filter(admission_type =="Emergency") %>%
#filter(speciality=="Accident & Emergency") %>%
#filter(year == 2020) %>%
filter(iswinter) %>%
group_by(hb_name) %>%
summarise(count_bad_days = sum(above_thresh),
count_days = n()*7,
pcnt_bad_days = 100*(sum(above_thresh)/(n()*7)),
mean_percentvar =mean(percent_variation)) %>%
ggplot() +
aes(x=hb_name, y=pcnt_bad_days) +
geom_col() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

take a look by health board
weekly_admissions_spec %>%
filter(speciality=="All") %>%
filter(admission_type =="Emergency") %>%
#filter(speciality=="Accident & Emergency") %>%
#filter(year == 2020) %>%
#filter(iswinter) %>%
group_by(hb_name) %>%
summarise(count_bad_days = sum(above_thresh),
count_days = n()*7,
pcnt_bad_days = 100*(sum(above_thresh)/(n()*7)),
mean_percentvar =mean(percent_variation)) %>%
ggplot() +
aes(x=hb_name, y=pcnt_bad_days) +
geom_col() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

quick look at winter v summer
weekly_admissions_spec %>%
filter(speciality=="Accident & Emergency") %>%
filter(admission_type =="All") %>%
group_by(iswinter, year) %>%
summarise(pcnt_bad_days = sum(above_thresh)/n()*7, mean_percentvar =mean(percent_variation))
`summarise()` has grouped output by 'iswinter'. You can override using the `.groups` argument.
no obvious big discrepancy in winter admissions for this parameter
winters of 2020 and 2022 are ‘worse’ than summers, percentages are small
and maybe not significant?
weekly_admissions_spec %>%
filter(speciality=="All") %>%
filter(admission_type =="All") %>%
group_by(iswinter, year) %>%
summarise(count_bad_days = sum(above_thresh),
count_days = n()*7,
pcnt_bad_days = 100*(sum(above_thresh)/(n()*7)),
mean_percentvar =mean(percent_variation)) %>%
ggplot() +
aes(x=iswinter, y=pcnt_bad_days) +
geom_col() +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
facet_grid(~year)
`summarise()` has grouped output by 'iswinter'. You can override using the `.groups` argument.

weekly_admissions_spec %>%
filter(speciality=="All") %>%
filter(admission_type =="Emergency") %>%
group_by(iswinter, year) %>%
summarise(count_bad_days = sum(above_thresh),
count_days = n()*7,
pcnt_bad_days = 100*(sum(above_thresh)/(n()*7)),
mean_percentvar =mean(percent_variation)) %>%
ggplot() +
aes(x=iswinter, y=pcnt_bad_days) +
geom_col() +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
facet_grid(~year)
`summarise()` has grouped output by 'iswinter'. You can override using the `.groups` argument.

weekly_admissions_spec %>%
filter(speciality=="Accident & Emergency") %>%
filter(admission_type =="Emergency") %>%
group_by(iswinter, year) %>%
summarise(count_bad_days = sum(above_thresh),
count_days = n()*7,
pcnt_bad_days = 100*(sum(above_thresh)/(n()*7)),
mean_percentvar =mean(percent_variation)) %>%
ggplot() +
aes(x=year, y=pcnt_bad_days) +
geom_col() +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
facet_grid(~iswinter)
`summarise()` has grouped output by 'iswinter'. You can override using the `.groups` argument.

#Section2 - repeat for demographic data
bad days by age group
weekly_admissions_demog %>%
filter(sex=="All") %>%
filter(admission_type =="All") %>%
filter(hb_name=="All Scotland") %>%
#filter(year == "2021") %>%
#filter(iswinter) %>%
group_by(age_group) %>%
summarise(count_bad_days = sum(above_thresh),
count_days = n()*7,
pcnt_bad_days = 100*(sum(above_thresh)/(n()*7)),
mean_percentvar = mean(percent_variation),
#trying a diff calc just to show its the same
percent_variation = 100*(sum(number_admissions)-sum(average20182019))
/sum(average20182019))
weekly_admissions_spec %>%
filter(speciality !="All") %>%
filter(admission_type =="All") %>%
filter(hb_name == "All Scotland") %>%
group_by(speciality) %>%
summarise(count_bad_days = sum(above_thresh),
count_days = n()*7,
pcnt_bad_days = 100*(sum(above_thresh)/(n()*7)),
mean_percentvar =mean(percent_variation)) %>%
ggplot() +
aes(x=speciality, y=pcnt_bad_days) +
geom_col() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

weekly_admissions_demog %>%
filter(sex=="All") %>%
filter(admission_type =="All") %>%
filter(hb_name=="All Scotland") %>%
group_by(age_group) %>%
summarise(count_bad_days = sum(above_thresh),
count_days = n()*7,
pcnt_bad_days = 100*(sum(above_thresh)/(n()*7)),
mean_percentvar =mean(percent_variation)) %>%
ggplot() +
aes(x=age_group, y=pcnt_bad_days) +
geom_col() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

weekly_admissions_demog %>%
filter(age_group=="All ages") %>%
filter(admission_type =="All") %>%
filter(hb_name=="All Scotland") %>%
group_by(sex) %>%
summarise(count_bad_days = sum(above_thresh),
count_days = n()*7,
pcnt_bad_days = 100*(sum(above_thresh)/(n()*7)),
mean_percentvar =mean(percent_variation)) %>%
ggplot() +
aes(x=sex, y=pcnt_bad_days) +
geom_col() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))

no obvious difference between sexes
weekly_admissions_dep %>%
filter(admission_type =="All") %>%
filter(hb_name=="All Scotland") %>%
group_by(simd_quintile, year) %>%
summarise(count_bad_days = sum(above_thresh),
count_days = n()*7,
pcnt_bad_days = 100*(sum(above_thresh)/(n()*7)),
mean_percentvar =mean(percent_variation)) %>%
ggplot() +
aes(x=simd_quintile, y=pcnt_bad_days) +
geom_col() +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
facet_grid(~year)
`summarise()` has grouped output by 'simd_quintile'. You can override using the `.groups` argument.

LS0tCnRpdGxlOiAiSW52ZXN0aWdhdGluZyBEYXRhIC0gQ292aWQgV2lkZXIgSW1wYWN0cyIKb3V0cHV0OiBodG1sX25vdGVib29rCmVkaXRvcl9vcHRpb25zOiAKICBjaHVua19vdXRwdXRfdHlwZTogaW5saW5lCi0tLQoKTG9va2luZyBhdCB3aWRlciBjb3ZpZCBpbXBhY3RzIGRhdGEKd2Vla2x5IHZhcmlhYmlsaXR5IC0gcmVsYXRlZCB0byAyMDE4LzE5IGJhc2VsaW5lCgpyZXZpc2VkIHZlcnNpb24gLSBub3cgZXh0cmFjdGluZyBhbGwgU2NvdGxhbmQgbW9yZSBlYXNpbHkuCgpgYGB7cn0KbGlicmFyeSgidGlkeXZlcnNlIikKbGlicmFyeSgiamFuaXRvciIpCmxpYnJhcnkoImx1YnJpZGF0ZSIpCmBgYAoKYGBge3J9CmhiX2NvZGVzIDwtIHJlYWRfY3N2KCJoZWFsdGhfYm9hcmRfY29kZXMuY3N2IikKaGJfY29kZXMgPC0gY2xlYW5fbmFtZXMoaGJfY29kZXMpCmBgYAoKbG9hZCBpbiBkYXRhZmlsZXMKCmBgYHtyfQp3ZWVrbHlfYWRtaXNzaW9uc19zcGVjIDwtIHJlYWRfY3N2KCJDb3ZpZCBhZG1pc3Npb25zIGJ5IGhlYWx0aCBib2FyZCBhbmQgc3BlY2lhbGl0eS5jc3YiKQp3ZWVrbHlfYWRtaXNzaW9uc19zcGVjIDwtIGNsZWFuX25hbWVzKHdlZWtseV9hZG1pc3Npb25zX3NwZWMpCgp3ZWVrbHlfYWRtaXNzaW9uc19kZXAgPC0gcmVhZF9jc3YoIkNvdmlkIGFkbWlzc2lvbnMgYnkgaGVhbHRoIGJvYXJkIGFuZCBkZXByaXZhdGlvbi5jc3YiKQp3ZWVrbHlfYWRtaXNzaW9uc19kZXAgPC0gY2xlYW5fbmFtZXMod2Vla2x5X2FkbWlzc2lvbnNfZGVwKQoKd2Vla2x5X2FkbWlzc2lvbnNfZGVtb2cgPC0gcmVhZF9jc3YoIkNvdmlkIGFkbWlzc2lvbnMgYnkgaGVhbHRoIGJvYXJkLCBhZ2UgYW5kIHNleC5jc3YiKQp3ZWVrbHlfYWRtaXNzaW9uc19kZW1vZyA8LSBjbGVhbl9uYW1lcyh3ZWVrbHlfYWRtaXNzaW9uc19kZW1vZykKYGBgCgpkYXRhIGNsZWFuaW5nCm5vdGUgcHJvYmFibHkgbW9yZSBjbGVhbmluZyBuZWVkZWQgYmVmb3JlIHdlIGZpbmFsaXNlCkkgY2hhbmdlZCB0aGUgc3BlbGxpbmcgYnV0IGl0IHR1cm5zIG91dCBib3RoIHNwZWxsaW5ncyBhcmUgY29ycmVjdCEKCmBgYHtyfQp3ZWVrbHlfYWRtaXNzaW9uc19zcGVjIDwtIHdlZWtseV9hZG1pc3Npb25zX3NwZWMgJT4lIAogIHJlbmFtZSgic3BlY2lhbGl0eSI9ICJzcGVjaWFsdHkiKSAlPiUgCiAgcmVuYW1lKCJzcGVjaWFsaXR5X3FmIj0gInNwZWNpYWx0eV9xZiIpIApgYGAKCm1lcmdlIGhibmFtZXMgaW50byBkYXRhZmlsZXMKYGBge3J9CndlZWtseV9hZG1pc3Npb25zX3NwZWMgPC0gbGVmdF9qb2luKHdlZWtseV9hZG1pc3Npb25zX3NwZWMsaGJfY29kZXMpCndlZWtseV9hZG1pc3Npb25zX2RlbW9nIDwtIGxlZnRfam9pbih3ZWVrbHlfYWRtaXNzaW9uc19kZW1vZyxoYl9jb2RlcykKd2Vla2x5X2FkbWlzc2lvbnNfZGVwIDwtIGxlZnRfam9pbih3ZWVrbHlfYWRtaXNzaW9uc19kZXAsaGJfY29kZXMpIApgYGAKCmRvIHRoZSBhbmFseXNpcyBuZWVkZWQgZm9yIGlkZW50aWZ5aW5nIHFpbnRlciBhbmQgJ2NyaXNpcycKCmBgYHtyfQp3ZWVrbHlfYWRtaXNzaW9uc19zcGVjIDwtIHdlZWtseV9hZG1pc3Npb25zX3NwZWMgJT4lIAogIG11dGF0ZSh5ZWFyID0gYXMuaW50ZWdlcihzdHJfc3ViKHdlZWtfZW5kaW5nLDEsNCkpKSAlPiUgCiAgbXV0YXRlKG1vbnRoID0gYXMuaW50ZWdlcihzdHJfc3ViKHdlZWtfZW5kaW5nLDUsNikpKSAlPiUgCiAgbXV0YXRlKGRheSA9IGFzLmludGVnZXIoc3RyX3N1Yih3ZWVrX2VuZGluZyw3LDgpKSkgJT4lIAogIG11dGF0ZSh3ZGF0ZSA9IHltZCh3ZWVrX2VuZGluZykpICU+JSAKICAjIGlkZW50aWZ5ICJBbGwgU2NvdGxhbmQiIGRhdGEKICBtdXRhdGUoaGJfbmFtZSA9IGlmZWxzZShoYj09IlM5MjAwMDAwMyIsIkFsbCBTY290bGFuZCIsaGJfbmFtZSkpICU+JSAKICBtdXRhdGUoaGJfbmFtZSA9IGlmZWxzZShpcy5uYShoYl9uYW1lKSwiTkhTIFJlZ2lvbiBVbmtub3duIixoYl9uYW1lKSkgJT4lIAogIG11dGF0ZShpc3dpbnRlciA9IGlmZWxzZShtb250aCAlaW4lIGMoNCw1LDYsNyw4LDkpLEZBTFNFLFRSVUUpKSAlPiUgCiAgbXV0YXRlKGFib3ZlX3RocmVzaCA9IGlmZWxzZShwZXJjZW50X3ZhcmlhdGlvbj4wLDcsMCkpCmBgYAoKYGBge3J9CndlZWtseV9hZG1pc3Npb25zX2RlbW9nIDwtIHdlZWtseV9hZG1pc3Npb25zX2RlbW9nICU+JSAKICBtdXRhdGUoeWVhciA9IGFzLmludGVnZXIoc3RyX3N1Yih3ZWVrX2VuZGluZywxLDQpKSkgJT4lIAogIG11dGF0ZShtb250aCA9IGFzLmludGVnZXIoc3RyX3N1Yih3ZWVrX2VuZGluZyw1LDYpKSkgJT4lIAogIG11dGF0ZShkYXkgPSBhcy5pbnRlZ2VyKHN0cl9zdWIod2Vla19lbmRpbmcsNyw4KSkpICU+JSAKICBtdXRhdGUod2RhdGUgPSB5bWQod2Vla19lbmRpbmcpKSAlPiUgCiAgIyBpZGVudGlmeSAiQWxsIFNjb3RsYW5kIiBkYXRhCiAgbXV0YXRlKGhiX25hbWUgPSBpZmVsc2UoaGI9PSJTOTIwMDAwMDMiLCJBbGwgU2NvdGxhbmQiLGhiX25hbWUpKSAlPiUgCiAgbXV0YXRlKGhiX25hbWUgPSBpZmVsc2UoaXMubmEoaGJfbmFtZSksIk5IUyBSZWdpb24gVW5rbm93biIsaGJfbmFtZSkpICU+JSAKICBtdXRhdGUoaXN3aW50ZXIgPSBpZmVsc2UobW9udGggJWluJSBjKDQsNSw2LDcsOCw5KSxGQUxTRSxUUlVFKSkgJT4lIAogIG11dGF0ZShhYm92ZV90aHJlc2ggPSBpZmVsc2UocGVyY2VudF92YXJpYXRpb24+MCw3LDApKQpgYGAKCmBgYHtyfQp3ZWVrbHlfYWRtaXNzaW9uc19kZXAgPC0gd2Vla2x5X2FkbWlzc2lvbnNfZGVwICU+JSAKICBtdXRhdGUoeWVhciA9IGFzLmludGVnZXIoc3RyX3N1Yih3ZWVrX2VuZGluZywxLDQpKSkgJT4lIAogIG11dGF0ZShtb250aCA9IGFzLmludGVnZXIoc3RyX3N1Yih3ZWVrX2VuZGluZyw1LDYpKSkgJT4lIAogIG11dGF0ZShkYXkgPSBhcy5pbnRlZ2VyKHN0cl9zdWIod2Vla19lbmRpbmcsNyw4KSkpICU+JSAKICBtdXRhdGUod2RhdGUgPSB5bWQod2Vla19lbmRpbmcpKSAlPiUgCiAgIyBpZGVudGlmeSAiQWxsIFNjb3RsYW5kIiBkYXRhCiAgbXV0YXRlKGhiX25hbWUgPSBpZmVsc2UoaGI9PSJTOTIwMDAwMDMiLCJBbGwgU2NvdGxhbmQiLGhiX25hbWUpKSAlPiUgCiAgbXV0YXRlKGhiX25hbWUgPSBpZmVsc2UoaXMubmEoaGJfbmFtZSksIk5IUyBSZWdpb24gVW5rbm93biIsaGJfbmFtZSkpICU+JSAKICBtdXRhdGUoaXN3aW50ZXIgPSBpZmVsc2UobW9udGggJWluJSBjKDQsNSw2LDcsOCw5KSxGQUxTRSxUUlVFKSkgJT4lIAogIG11dGF0ZShhYm92ZV90aHJlc2ggPSBpZmVsc2UocGVyY2VudF92YXJpYXRpb24+MCw3LDApKQpgYGAKCnRha2UgYSBsb29rIGF0IHdoYXQgaXMgaW4gZWFjaCBkYXRhc2V0CgpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfc3BlYyAlPiUgCiAgZGlzdGluY3QoaGJfbmFtZSkKYGBgCjE0IGhlYWx0aCBib2FyZHMgcGx1cyAnYWxsIHNjb3RsYW5kJyBhbmQgYW4gTkEgLSBuZWVkIHRvIHdvcmsgb3V0IHdoYXQgdG8gZG8gd2l0aCB0aGlzCgpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfc3BlYyAlPiUgCiAgZGlzdGluY3QoYWRtaXNzaW9uX3R5cGUpCmBgYApEYXRhIG5lYXRseSBkaXZpZGVkIGludG8gZW1lcmdlbmN5IGFuZCBwbGFubmVkCmBgYHtyfQp3ZWVrbHlfYWRtaXNzaW9uc19zcGVjICU+JSAKICBkaXN0aW5jdChzcGVjaWFsaXR5KQpgYGAKbm90ZSB0aGF0IHNvbWUgZ3JvdXBpbmdzIGFyZSBhbHNvIGNvbWJpbmVkLiBuZWVkIHRvIHRha2UgYSBjbG9zZXIgbG9vayBhdCB3aGF0IHRoZXNlIG1lYW4uCgpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfZGVtb2cgJT4lIAogIGRpc3RpbmN0KGFnZV9ncm91cCkKYGBgCjcgYWdlIGdyb3VwcyBhbmQgImFsbCBhZ2VzIgoKYGBge3J9CndlZWtseV9hZG1pc3Npb25zX2RlbW9nICU+JSAKICBkaXN0aW5jdChzZXgpCmBgYApqdXN0IG1hbGUgLSBmZW1hbGUgYW5kIGFsbAoKYGBge3J9CndlZWtseV9hZG1pc3Npb25zX2RlcCAlPiUgCiAgZGlzdGluY3Qoc2ltZF9xdWludGlsZSkKYGBgCm5vdGUgdGhlcmUgaXMgbm8gJ2FsbCcgY2F0ZWdvcnkgaW4gdGhpcyBkYXRhc2V0CgpwbG90IHRvdGFsIGFkbWlzc2lvbnMgLSB5b3Ugc2hvdWxkIGdldCB0aGUgc2FtZSBvdmVyYWxsIHRyZW5kcyBmcm9tIGVhY2ggZGF0YXNldApgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfZGVtb2cgJT4lIAogIGZpbHRlcihhZ2VfZ3JvdXAgPT0gIkFsbCBhZ2VzIikgJT4lIAogIGZpbHRlcihzZXggPT0iQWxsIikgJT4lIAogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSAiQWxsIikgJT4lIAogIGZpbHRlcihoYl9uYW1lID09IkFsbCBTY290bGFuZCIpICU+JSAKZ2dwbG90KCkgKwphZXMoeD13ZGF0ZSwgeSA9IG51bWJlcl9hZG1pc3Npb25zKSArCmdlb21fbGluZShjb2xvdXI9J3JlZCcpIApgYGAKCgpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfc3BlYyAlPiUgCiAgZmlsdGVyKHNwZWNpYWxpdHkgPT0gIkFsbCIpICU+JSAKICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkFsbCIpICU+JSAKICBmaWx0ZXIoaGJfbmFtZSA9PSJBbGwgU2NvdGxhbmQiKSAlPiUgCmdncGxvdCgpICsKYWVzKHg9d2RhdGUsIHkgPSBudW1iZXJfYWRtaXNzaW9ucykgKwpnZW9tX2xpbmUoY29sb3VyPSdyZWQnKSAKYGBgCnNhbWUgZ3JhcGggYXMgYWJvdmUhCgp3ZWVrbHkgaG9zcGl0YWwgYWRtaXNzaW9ucyBob3ZlciBhcm91bmQgMTQwMDAgcGVyIHdlZWsKZXhwZWN0IDE2OCwwMDAgcGVyIHF1YXJ0ZXI/CgpwcmU9cGFuZGVtaWMgaG9zcGl0YWwgYWRtaXNzaW9ucyBob3ZlcmVkIGFyb3VuZCAxNTUwMCBwZXIgd2VlawpleHBlY3QgMTg2LDAwMCBwZXIgcXVhcnRlcgoKYGBge3J9CndlZWtseV9hZG1pc3Npb25zX3NwZWMgJT4lIAogIGZpbHRlcihzcGVjaWFsaXR5ID09ICJBbGwiKSAlPiUgCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJBbGwiKSAlPiUgCiAgZmlsdGVyKGhiX25hbWUgPT0iQWxsIFNjb3RsYW5kIikgJT4lIApnZ3Bsb3QoKSArCmFlcyh4PXdkYXRlLCB5ID0gcGVyY2VudF92YXJpYXRpb24pICsKZ2VvbV9saW5lKGNvbG91cj0ncmVkJykgCmBgYAoKT3ZlcmFsbChhbGwgc3BlY2lhbGl0aWVzLCBhbGwgYWRtaXNzaW9ucywgYWxsIGhlYWx0aGJvYXJkcykgYWRtaXNzaW9ucyBhcmUgb25seSBhdCA5MCUgb2YgcHJlLXBhbmRlbWljIGxldmVscwoKCnF1aWNrIGxvb2sgYXQgZGVtb2dyYXBoaWNzCgpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfZGVtb2cgJT4lIAogIGZpbHRlcihzZXggPT0gIkFsbCIpICU+JSAKICBmaWx0ZXIoYWdlX2dyb3VwICE9ICJBbGwgYWdlcyIpICU+JSAKICBmaWx0ZXIoaGJfbmFtZSA9PSJBbGwgU2NvdGxhbmQiKSAlPiUgCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJBbGwiKSAlPiUgCmdncGxvdCgpICsKYWVzKHg9d2RhdGUsIHkgPSBudW1iZXJfYWRtaXNzaW9ucywgY29sb3IgPSBhZ2VfZ3JvdXApICsKZ2VvbV9saW5lKCkgIysKI3NjYWxlX2NvbG91cl9icmV3ZXIocGFsZXR0ZSA9ICJTZXQyIikgCmBgYAphZ2UgcGxvdCBzaG93cyBzb21lIHZhcmlhdGlvbiBiZXR3ZWVuIGFnZSBncm91cHMuCgpxdWljayBsb29rIGF0IHNleCBkaWZmZXJlbmNlcwpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfZGVtb2cgJT4lIAogIGZpbHRlcihzZXggIT0gIkFsbCIpICU+JSAKICBmaWx0ZXIoYWdlX2dyb3VwID09ICJBbGwgYWdlcyIpICU+JSAKICBmaWx0ZXIoaGJfbmFtZSA9PSJBbGwgU2NvdGxhbmQiKSAlPiUgCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJBbGwiKSAlPiUgCmdncGxvdCgpICsKYWVzKHg9d2RhdGUsIHkgPSBwZXJjZW50X3ZhcmlhdGlvbiwgY29sb3IgPSBzZXgpICsKZ2VvbV9saW5lKCkgIysKI3NjYWxlX2NvbG91cl9icmV3ZXIocGFsZXR0ZSA9ICJTZXQyIikgCmBgYAoKcXVpY2sgbG9vayBhdCBpbmRleCBvZiBkZXByaXZhdGlvbi4gMSBpcyBtb3N0IGRlcHJpdmVkIGFuZCA1IGlzIGxlYXN0IGRlcHJpdmVkCgpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfZGVwICU+JSAKICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkFsbCIpICU+JSAKICBmaWx0ZXIoaGJfbmFtZSA9PSJBbGwgU2NvdGxhbmQiKSAlPiUgCmdncGxvdCgpICsKYWVzKHg9d2RhdGUsIHkgPSBwZXJjZW50X3ZhcmlhdGlvbiwgY29sb3IgPSBhcy5mYWN0b3Ioc2ltZF9xdWludGlsZSkpICsKZ2VvbV9saW5lKCkgCmBgYApzb21ldGhpbmcgaGFwcGVuaW5nIGluIDIwMjIgLSB3aHkgaXMgdGhlcmUgZGl2ZXJnZW5jZSBiZXR3ZWVuIDEgYW5kIDU/CgoKCmxvb2sgYXQgYWRtaXNzaW9ucyB0eXBlCmBgYHtyfQp3ZWVrbHlfYWRtaXNzaW9uc19zcGVjICU+JSAKICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgIT0gIkFsbCIpICU+JSAKICBmaWx0ZXIoc3BlY2lhbGl0eT09IkFsbCIpICU+JSAKICBmaWx0ZXIoaGJfbmFtZSA9PSJBbGwgU2NvdGxhbmQiKSAlPiUgCmdncGxvdCgpICsKYWVzKHg9d2RhdGUsIHkgPSBwZXJjZW50X3ZhcmlhdGlvbiwgY29sb3VyID0gYWRtaXNzaW9uX3R5cGUpICsKZ2VvbV9saW5lKCkKYGBgCm5lZWQgdG8gY2hlY2sgd2hhdCB0aGUgJ3NwaWtlJyBpbiBwbGFubmVkIGF0IGVuZCBvZiAyMDIxIGlzIHJlbGF0ZWQgdG8KCnF1aWNrIGxvb2sgYXQgc3BlY2lhbGl0aWVzCmBgYHtyfQp3ZWVrbHlfYWRtaXNzaW9uc19zcGVjICU+JSAKICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkFsbCIpICU+JSAKICBmaWx0ZXIoc3BlY2lhbGl0eSAhPSJBbGwiKSAlPiUgCiAgZmlsdGVyKGhiX25hbWUgPT0iQWxsIFNjb3RsYW5kIikgJT4lIApnZ3Bsb3QoKSArCmFlcyh4PXdkYXRlLCB5ID0gcGVyY2VudF92YXJpYXRpb24sIGNvbG91cj1zcGVjaWFsaXR5KSArCmdlb21fbGluZSgpCmBgYAp0YWtlIGEgY2xvc2VyIGxvb2sgYXQgcGFlZGlhdHJpY3MKYGBge3J9CndlZWtseV9hZG1pc3Npb25zX3NwZWMgJT4lIAogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSAiQWxsIikgJT4lIAogIGZpbHRlcihzcGVjaWFsaXR5ICE9IkFsbCIpICU+JSAKICBmaWx0ZXIoc3RyX2RldGVjdChzcGVjaWFsaXR5LCJQYWVkIikpICU+JSAKICBmaWx0ZXIoaGJfbmFtZSA9PSJBbGwgU2NvdGxhbmQiKSAlPiUgCmdncGxvdCgpICsKYWVzKHg9d2RhdGUsIHkgPSBudW1iZXJfYWRtaXNzaW9ucywgY29sb3VyPXNwZWNpYWxpdHkpICsKZ2VvbV9saW5lKCkKYGBgCgoKYGBge3J9CndlZWtseV9hZG1pc3Npb25zX3NwZWMgJT4lIAogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSAiQWxsIikgJT4lIAogIGZpbHRlcihzcGVjaWFsaXR5ICE9IkFsbCIpICU+JSAKICBmaWx0ZXIoc3RyX2RldGVjdChzcGVjaWFsaXR5LCJQYWVkIikpICU+JSAKICBmaWx0ZXIoaGJfbmFtZSA9PSJBbGwgU2NvdGxhbmQiKSAlPiUgCmdncGxvdCgpICsKYWVzKHg9d2RhdGUsIHkgPSBwZXJjZW50X3ZhcmlhdGlvbiwgY29sb3VyPXNwZWNpYWxpdHkpICsKZ2VvbV9saW5lKCkKYGBgCnRha2UgYSBjbG9zZXIgbG9vayBhdCBtZWRpY2FsCgpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfc3BlYyAlPiUgCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJBbGwiKSAlPiUgCiAgZmlsdGVyKHNwZWNpYWxpdHkgIT0iQWxsIikgJT4lIAogIGZpbHRlcihzdHJfZGV0ZWN0KHNwZWNpYWxpdHksIk1lZGljYWwiKSkgJT4lIAogIGZpbHRlcihoYl9uYW1lID09IkFsbCBTY290bGFuZCIpICU+JSAKZ2dwbG90KCkgKwphZXMoeD13ZGF0ZSwgeSA9IHBlcmNlbnRfdmFyaWF0aW9uLCBjb2xvdXI9c3BlY2lhbGl0eSkgKwpnZW9tX2xpbmUoKQpgYGAKc2ltcGxlciBwbG90IG9mIHNwZWNpYWxpdGllcwpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfc3BlYyAlPiUgCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJQbGFubmVkIikgJT4lIAogIGZpbHRlcihzcGVjaWFsaXR5ICE9Ik1lZGljYWwgKGluY2wuIENhcmRpb2xvZ3kgJiBDYW5jZXIpIikgJT4lIAogIGZpbHRlcighc3RyX2RldGVjdChzcGVjaWFsaXR5LCJQYWVkIikpICU+JSAKICBmaWx0ZXIoc3BlY2lhbGl0eSAhPSJBbGwiKSAlPiUgCiAgZmlsdGVyKHNwZWNpYWxpdHkgIT0iQWNjaWRlbnQgJiBFbWVyZ2VuY3kiKSAlPiUgCiAgZmlsdGVyKGhiX25hbWUgPT0iQWxsIFNjb3RsYW5kIikgJT4lIApnZ3Bsb3QoKSArCmFlcyh4PXdkYXRlLCB5ID0gcGVyY2VudF92YXJpYXRpb24sIGNvbG91cj1zcGVjaWFsaXR5KSArCmdlb21fbGluZSgpICsKc2NhbGVfY29sb3VyX2JyZXdlcihwYWxldHRlID0gIlNldDEiKSAKYGBgCgpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfc3BlYyAlPiUgCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJFbWVyZ2VuY3kiKSAlPiUgCiAgZmlsdGVyKHNwZWNpYWxpdHkgIT0iTWVkaWNhbCAoaW5jbC4gQ2FyZGlvbG9neSAmIENhbmNlcikiKSAlPiUgCiAgZmlsdGVyKCFzdHJfZGV0ZWN0KHNwZWNpYWxpdHksIlBhZWQiKSkgJT4lIAogIGZpbHRlcihzcGVjaWFsaXR5ICE9IkFsbCIpICU+JSAKICBmaWx0ZXIoc3BlY2lhbGl0eSAhPSJBY2NpZGVudCAmIEVtZXJnZW5jeSIpICU+JSAKICBmaWx0ZXIoaGJfbmFtZSA9PSJBbGwgU2NvdGxhbmQiKSAlPiUgCmdncGxvdCgpICsKYWVzKHg9d2RhdGUsIHkgPSBwZXJjZW50X3ZhcmlhdGlvbiwgY29sb3VyPXNwZWNpYWxpdHkpICsKZ2VvbV9saW5lKCkgKwpzY2FsZV9jb2xvdXJfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpIApgYGAKYm94cGxvdCBmb3IgZGlmZmVyZW50IHNwZWNpYWxpdGllcz8gc29tZSB2YWx1ZXMgZ3JlYXRlciB0aGFuIDgwMDAlIChpIGhhdmUgZmlsdGVyZWQgdGhlbSBvdXQgKSBpbmRpY2F0ZXMgd2UgbmVlZCBzb21lIG1vcmUgd29yayBvbiBkYXRhIGNsZWFuaW5nIQoKYGBge3J9CndlZWtseV9hZG1pc3Npb25zX3NwZWMgJT4lIAogICNmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkFsbCIpICU+JSAKICAjZmlsdGVyKHNwZWNpYWxpdHkhPSJBbGwiKSAlPiUgCiAgI2ZpbHRlcihoYl9uYW1lID09Ik5IUyBSZWdpb24gVW5rbm93biIpICU+JSAKICAjZ3JvdXBfYnkoc3BlY2lhbGl0eSkgJT4lIAogICNuZWVkIHRvIHRha2UgYSBnb29kIGxvb2sgYXQgd2hhdCB0aGVzZSB2YWx1ZXMgYXJlIQogIGZpbHRlcihwZXJjZW50X3ZhcmlhdGlvbj41MDApIApgYGAKCgpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfc3BlYyAlPiUgCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJBbGwiKSAlPiUgCiAgZmlsdGVyKHNwZWNpYWxpdHkhPSJBbGwiKSAlPiUgCiAgZ3JvdXBfYnkoc3BlY2lhbGl0eSkgJT4lIAogICNuZWVkIHRvIHRha2UgYSBnb29kIGxvb2sgYXQgd2hhdCB0aGVzZSB2YWx1ZXMgYXJlIQogIGZpbHRlcihwZXJjZW50X3ZhcmlhdGlvbjw4MDAwKSAlPiUgCiAgZ2dwbG90KCkrCiAgYWVzKHg9c3BlY2lhbGl0eSwgeT1wZXJjZW50X3ZhcmlhdGlvbikrCiAgZ2VvbV9ib3hwbG90KCkrCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkKYGBgCnNvbWUgc3BlY2lhbGl0aWVzIGhhdmUgZmFjZWQgaGlnaGVyIGFkbWlzc2lvbiBsZXZlbHMgdGhhbiBvdGhlcnMuCgoKTm93IGxvb2sgYnkgaGVhbHRoIGJvYXJkcyAKCmBgYHtyfQphbGxfYWRtaXNzaW9uc19ieWhiIDwtIHdlZWtseV9hZG1pc3Npb25zICU+JSAKICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkFsbCIpICU+JSAKICBmaWx0ZXIoc3BlY2lhbGl0eT09IkFsbCIpICU+JSAKICBncm91cF9ieShoYl9uYW1lKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fcGVyY250X3ZhciA9IG1lYW4ocGVyY2VudF92YXJpYXRpb24pLAogICAgICAgICAgICBtaW5fcGVyY250X3ZhciA9IG1pbihwZXJjZW50X3ZhcmlhdGlvbiksCiAgICAgICAgICAgIG1heF9wZXJjbnRfdmFyID0gbWF4KHBlcmNlbnRfdmFyaWF0aW9uKQogICAgICAgICAgICkgJT4lCiAgI211dGF0ZShhbGxfcGVyY2VudF92YXJpYXRpb24gPSBhbGxfYWRtaXNzaW9ucy9hbGxfYXZnMjAxODIwMTkpICAKICBhcnJhbmdlKGRlc2MobWF4X3BlcmNudF92YXIpKQphbGxfYWRtaXNzaW9uc19ieWhiCmBgYApgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfc3BlYyAlPiUgCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJBbGwiKSAlPiUgCiAgZmlsdGVyKHNwZWNpYWxpdHk9PSJBbGwiKSAlPiUgCiAgZ3JvdXBfYnkoaGJfbmFtZSkgJT4lIAogIGdncGxvdCgpKwogIGFlcyh4PXdkYXRlLCB5PXBlcmNlbnRfdmFyaWF0aW9uLCBjb2xvdXIgPSBoYl9uYW1lKSsKICBnZW9tX2xpbmUoKQpgYGAKCmBgYHtyfQp3ZWVrbHlfYWRtaXNzaW9uc19zcGVjICU+JSAKICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkFsbCIpICU+JSAKICBmaWx0ZXIoc3BlY2lhbGl0eT09IkFsbCIpICU+JSAKICBncm91cF9ieShoYl9uYW1lKSAlPiUgCiAgZ2dwbG90KCkrCiAgYWVzKHg9aGJfbmFtZSwgeT1wZXJjZW50X3ZhcmlhdGlvbikrCiAgZ2VvbV9ib3hwbG90KCkrCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkKYGBgCgoKZm9yIHNvbWUgaGVhbHRoIGJvYXJkcyBhIHNpZ25pZmljYW50IG51bWJlciBvZiBhZG1pc3Npb25zIGxldmVscyBhcmUgYWJvdmUgdGhlIGxldmVscyBzZWVuIGluIDIwMTgtMTkuIGNvdWxkIHdlIHBhcmhhcHMgdHJ5IGFuZCB1c2UgdGhpcyBhcyBhbiBpbmRpY2F0b3I/CgpOZWVkIHRvIHRoaW5rIG1vcmUgY2FyZWZ1bGx5IGFib3V0IHdoYXQgdGhlIGRhdGEgaW4gJ3JlZ2lvbiB1bmtub3duJyBtZWFucyAKCgpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfc3BlYyAlPiUgCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJBbGwiKSAlPiUgCiAgZmlsdGVyKHNwZWNpYWxpdHk9PSJBbGwiKSAlPiUgCiAgZ2dwbG90KCkgKwogIGFlcyh4PXdkYXRlLCB5PXBlcmNlbnRfdmFyaWF0aW9uLCBjb2xvdXI9aGJfbmFtZSkgKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmhiX25hbWUpCmBgYApIb3cgaXMgTkEgY2FsY3VsYXRlZCAtIHN0aWxsIG5lZWQgdG8gY2hlY2s/PwoKYGBge3J9CndlZWtseV9hZG1pc3Npb25zX3NwZWMgJT4lIAogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSAiQWxsIikgJT4lIAogIGZpbHRlcihzcGVjaWFsaXR5ID09ICJBbGwiKSAlPiUgCiAgZmlsdGVyKGhiX25hbWUgIT0gIkFsbCBTY290bGFuZCIpICU+JSAKZ2dwbG90KCkgKwphZXMoeD13ZGF0ZSwgeSA9IG51bWJlcl9hZG1pc3Npb25zLCBjb2xvdXIgPSBoYl9uYW1lKSArCmdlb21fbGluZSgpCmBgYAphZG1pc3Npb24gdmFsdWVzIHNob3dzIGFsbCBoZWFsdGggYm9hcmRzIC0gaGVhbHRoIGJvYXJkcyB2YXJ5IG1hc3NpdmVseSBpbiBzaXplIGFuZCBhZG1pc3Npb24gbnVtYmVycyBidXQgbW9zdGx5IHNhbWUgb3ZlcmFsbCBwYXR0ZXJuLgoKYGBge3J9CndlZWtseV9hZG1pc3Npb25zX3NwZWMgJT4lIAogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSAiQWxsIikgJT4lIAogIGZpbHRlcihzcGVjaWFsaXR5PT0iQWNjaWRlbnQgJiBFbWVyZ2VuY3kiKSAlPiUgCiAgI3Rha2UgYSBnb29kIGxvb2sgYXQgd2hhdCB0aGVzZSB2YWx1ZXMgYXJlIQogIGZpbHRlcihwZXJjZW50X3ZhcmlhdGlvbjw4MDAwKSAlPiUgCiAgZ3JvdXBfYnkoaGJfbmFtZSkgJT4lIAogIGdncGxvdCgpKwogIGFlcyh4PWhiX25hbWUsIHk9cGVyY2VudF92YXJpYXRpb24pKwogIGdlb21fYm94cGxvdCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQpgYGAKZG8gb25seSBjZXJ0YWluIGhlYWx0aCBib2FyZHMgaGF2ZSBhbiBBK0UgZGVwdD8KCmBgYHtyfQp3ZWVrbHlfYWRtaXNzaW9uc19zcGVjICU+JSAKICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkVtZXJnZW5jeSIpICU+JSAKICAjZmlsdGVyKHNwZWNpYWxpdHk9PSJBY2NpZGVudCAmIEVtZXJnZW5jeSIpICU+JSAKICAjdGFrZSBhIGdvb2QgbG9vayBhdCB3aGF0IHRoZXNlIHZhbHVlcyBhcmUhCiAgZmlsdGVyKHBlcmNlbnRfdmFyaWF0aW9uPDgwMDApICU+JSAKICBncm91cF9ieShoYl9uYW1lKSAlPiUgCiAgZ2dwbG90KCkrCiAgYWVzKHg9aGJfbmFtZSwgeT1wZXJjZW50X3ZhcmlhdGlvbikrCiAgZ2VvbV9ib3hwbG90KCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpCmBgYAoKZmlyc3QgYXR0ZW1wdCBhdCBhICdjcmlzaXMnIGNhbGN1bGF0aW9uCgpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnMgJT4lIAogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSAiQWxsIikgJT4lIAogIGZpbHRlcihzcGVjaWFsaXR5PT0iQWxsIikgJT4lIAogICNmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0iRW1lcmdlbmN5IikgJT4lIAogICNmaWx0ZXIoc3BlY2lhbGl0eT09IkFjY2lkZW50ICYgRW1lcmdlbmN5IikgJT4lIAogICNmaWx0ZXIoeWVhciA9PSAyMDIwKSAlPiUgCiAgZmlsdGVyKGlzd2ludGVyKSAlPiUKICBncm91cF9ieShoYl9uYW1lKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50X2JhZF9kYXlzID0gc3VtKGFib3ZlX3RocmVzaCksIAogICAgICAgICAgICBjb3VudF9kYXlzID0gbigpKjcsIAogICAgICAgICAgICBwY250X2JhZF9kYXlzID0gMTAwKihzdW0oYWJvdmVfdGhyZXNoKS8obigpKjcpKSwgCiAgICAgICAgICAgIG1lYW5fcGVyY2VudHZhciA9bWVhbihwZXJjZW50X3ZhcmlhdGlvbikpICU+JQogIGdncGxvdCgpICsKICBhZXMoeD1oYl9uYW1lLCB5PW1lYW5fcGVyY2VudHZhcikgKwogIGdlb21fY29sKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpCmBgYAoKYGBge3J9CndlZWtseV9hZG1pc3Npb25zX3NwZWMgJT4lIAogIGZpbHRlcihzcGVjaWFsaXR5PT0iQWxsIikgJT4lIAogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSJBbGwiKSAlPiUgCiAgI2ZpbHRlcih5ZWFyID09IDIwMjEpICU+JSAKICAjZmlsdGVyKGlzd2ludGVyKSAlPiUKICBncm91cF9ieShoYl9uYW1lKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50X2JhZF9kYXlzID0gc3VtKGFib3ZlX3RocmVzaCksIAogICAgICAgICAgICBjb3VudF9kYXlzID0gbigpKjcsIAogICAgICAgICAgICBwY250X2JhZF9kYXlzID0gMTAwKihzdW0oYWJvdmVfdGhyZXNoKS8obigpKjcpKSwgCiAgICAgICAgICAgIG1lYW5fcGVyY2VudHZhciA9bWVhbihwZXJjZW50X3ZhcmlhdGlvbikpICU+JQogIGdncGxvdCgpICsKICBhZXMoeD1oYl9uYW1lLCB5PXBjbnRfYmFkX2RheXMpICsKICBnZW9tX2NvbCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQpgYGAKYGBge3J9CndlZWtseV9hZG1pc3Npb25zX3NwZWMgJT4lIAogIGZpbHRlcihzcGVjaWFsaXR5PT0iQWxsIikgJT4lIAogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSJFbWVyZ2VuY3kiKSAlPiUgCiAgI2ZpbHRlcihzcGVjaWFsaXR5PT0iQWNjaWRlbnQgJiBFbWVyZ2VuY3kiKSAlPiUgCiAgI2ZpbHRlcih5ZWFyID09IDIwMjApICU+JSAKICBmaWx0ZXIoaXN3aW50ZXIpICU+JQogIGdyb3VwX2J5KGhiX25hbWUpICU+JSAKICBzdW1tYXJpc2UoY291bnRfYmFkX2RheXMgPSBzdW0oYWJvdmVfdGhyZXNoKSwgCiAgICAgICAgICAgIGNvdW50X2RheXMgPSBuKCkqNywgCiAgICAgICAgICAgIHBjbnRfYmFkX2RheXMgPSAxMDAqKHN1bShhYm92ZV90aHJlc2gpLyhuKCkqNykpLCAKICAgICAgICAgICAgbWVhbl9wZXJjZW50dmFyID1tZWFuKHBlcmNlbnRfdmFyaWF0aW9uKSkgJT4lCiAgZ2dwbG90KCkgKwogIGFlcyh4PWhiX25hbWUsIHk9cGNudF9iYWRfZGF5cykgKwogIGdlb21fY29sKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpCmBgYAp0YWtlIGEgbG9vayBieSBoZWFsdGggYm9hcmQKCmBgYHtyfQp3ZWVrbHlfYWRtaXNzaW9uc19zcGVjICU+JSAKICBmaWx0ZXIoc3BlY2lhbGl0eT09IkFsbCIpICU+JSAKICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0iRW1lcmdlbmN5IikgJT4lIAogICNmaWx0ZXIoc3BlY2lhbGl0eT09IkFjY2lkZW50ICYgRW1lcmdlbmN5IikgJT4lIAogICNmaWx0ZXIoeWVhciA9PSAyMDIwKSAlPiUgCiAgI2ZpbHRlcihpc3dpbnRlcikgJT4lCiAgZ3JvdXBfYnkoaGJfbmFtZSkgJT4lIAogIHN1bW1hcmlzZShjb3VudF9iYWRfZGF5cyA9IHN1bShhYm92ZV90aHJlc2gpLCAKICAgICAgICAgICAgY291bnRfZGF5cyA9IG4oKSo3LCAKICAgICAgICAgICAgcGNudF9iYWRfZGF5cyA9IDEwMCooc3VtKGFib3ZlX3RocmVzaCkvKG4oKSo3KSksIAogICAgICAgICAgICBtZWFuX3BlcmNlbnR2YXIgPW1lYW4ocGVyY2VudF92YXJpYXRpb24pKSAlPiUKICBnZ3Bsb3QoKSArCiAgYWVzKHg9aGJfbmFtZSwgeT1wY250X2JhZF9kYXlzKSArCiAgZ2VvbV9jb2woKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkKYGBgCgoKcXVpY2sgbG9vayBhdCB3aW50ZXIgdiBzdW1tZXIKCmBgYHtyfQp3ZWVrbHlfYWRtaXNzaW9uc19zcGVjICU+JSAKICBmaWx0ZXIoc3BlY2lhbGl0eT09IkFjY2lkZW50ICYgRW1lcmdlbmN5IikgJT4lIAogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSJBbGwiKSAlPiUgCiAgZ3JvdXBfYnkoaXN3aW50ZXIsIHllYXIpICU+JSAKICBzdW1tYXJpc2UocGNudF9iYWRfZGF5cyA9IHN1bShhYm92ZV90aHJlc2gpL24oKSo3LCBtZWFuX3BlcmNlbnR2YXIgPW1lYW4ocGVyY2VudF92YXJpYXRpb24pKSAKYGBgCiAgbm8gb2J2aW91cyBiaWcgZGlzY3JlcGFuY3kgaW4gd2ludGVyIGFkbWlzc2lvbnMgZm9yIHRoaXMgcGFyYW1ldGVyCiAgd2ludGVycyBvZiAyMDIwIGFuZCAyMDIyIGFyZSAnd29yc2UnIHRoYW4gc3VtbWVycywgcGVyY2VudGFnZXMgYXJlIHNtYWxsIGFuZCBtYXliZSBub3QgICAgICAgICAgc2lnbmlmaWNhbnQ/IAoKYGBge3J9CndlZWtseV9hZG1pc3Npb25zX3NwZWMgJT4lIAogIGZpbHRlcihzcGVjaWFsaXR5PT0iQWxsIikgJT4lIAogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSJBbGwiKSAlPiUgCiAgZ3JvdXBfYnkoaXN3aW50ZXIsIHllYXIpICU+JSAKICBzdW1tYXJpc2UoY291bnRfYmFkX2RheXMgPSBzdW0oYWJvdmVfdGhyZXNoKSwgCiAgICAgICAgICAgIGNvdW50X2RheXMgPSBuKCkqNywgCiAgICAgICAgICAgIHBjbnRfYmFkX2RheXMgPSAxMDAqKHN1bShhYm92ZV90aHJlc2gpLyhuKCkqNykpLCAKICAgICAgICAgICAgbWVhbl9wZXJjZW50dmFyID1tZWFuKHBlcmNlbnRfdmFyaWF0aW9uKSkgJT4lIAogIGdncGxvdCgpICsKICBhZXMoeD1pc3dpbnRlciwgeT1wY250X2JhZF9kYXlzKSArCiAgZ2VvbV9jb2woKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkgKwogIGZhY2V0X2dyaWQofnllYXIpCmBgYApgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfc3BlYyAlPiUgCiAgZmlsdGVyKHNwZWNpYWxpdHk9PSJBbGwiKSAlPiUgCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09IkVtZXJnZW5jeSIpICU+JSAKICBncm91cF9ieShpc3dpbnRlciwgeWVhcikgJT4lIAogIHN1bW1hcmlzZShjb3VudF9iYWRfZGF5cyA9IHN1bShhYm92ZV90aHJlc2gpLCAKICAgICAgICAgICAgY291bnRfZGF5cyA9IG4oKSo3LCAKICAgICAgICAgICAgcGNudF9iYWRfZGF5cyA9IDEwMCooc3VtKGFib3ZlX3RocmVzaCkvKG4oKSo3KSksIAogICAgICAgICAgICBtZWFuX3BlcmNlbnR2YXIgPW1lYW4ocGVyY2VudF92YXJpYXRpb24pKSAlPiUgCiAgZ2dwbG90KCkgKwogIGFlcyh4PWlzd2ludGVyLCB5PXBjbnRfYmFkX2RheXMpICsKICBnZW9tX2NvbCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArCiAgZmFjZXRfZ3JpZCh+eWVhcikKYGBgCmBgYHtyfQp3ZWVrbHlfYWRtaXNzaW9uc19zcGVjICU+JSAKICBmaWx0ZXIoc3BlY2lhbGl0eT09IkFjY2lkZW50ICYgRW1lcmdlbmN5IikgJT4lIAogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSJFbWVyZ2VuY3kiKSAlPiUgCiAgZ3JvdXBfYnkoaXN3aW50ZXIsIHllYXIpICU+JSAKICBzdW1tYXJpc2UoY291bnRfYmFkX2RheXMgPSBzdW0oYWJvdmVfdGhyZXNoKSwgCiAgICAgICAgICAgIGNvdW50X2RheXMgPSBuKCkqNywgCiAgICAgICAgICAgIHBjbnRfYmFkX2RheXMgPSAxMDAqKHN1bShhYm92ZV90aHJlc2gpLyhuKCkqNykpLCAKICAgICAgICAgICAgbWVhbl9wZXJjZW50dmFyID1tZWFuKHBlcmNlbnRfdmFyaWF0aW9uKSkgJT4lIAogIGdncGxvdCgpICsKICBhZXMoeD15ZWFyLCB5PXBjbnRfYmFkX2RheXMpICsKICBnZW9tX2NvbCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArCiAgZmFjZXRfZ3JpZCh+aXN3aW50ZXIpCmBgYAoKCiNTZWN0aW9uMiAtIHJlcGVhdCBmb3IgZGVtb2dyYXBoaWMgZGF0YQoKYmFkIGRheXMgYnkgYWdlIGdyb3VwCgpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfZGVtb2cgJT4lIAogIGZpbHRlcihzZXg9PSJBbGwiKSAlPiUgCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09IkFsbCIpICU+JSAKICBmaWx0ZXIoaGJfbmFtZT09IkFsbCBTY290bGFuZCIpICU+JSAKICAjZmlsdGVyKHllYXIgPT0gIjIwMjEiKSAlPiUgCiAgI2ZpbHRlcihpc3dpbnRlcikgJT4lIAogIGdyb3VwX2J5KGFnZV9ncm91cCkgJT4lIAogIHN1bW1hcmlzZShjb3VudF9iYWRfZGF5cyA9IHN1bShhYm92ZV90aHJlc2gpLCAKICAgICAgICAgICAgY291bnRfZGF5cyA9IG4oKSo3LCAKICAgICAgICAgICAgcGNudF9iYWRfZGF5cyA9IDEwMCooc3VtKGFib3ZlX3RocmVzaCkvKG4oKSo3KSksIAogICAgICAgICAgICBtZWFuX3BlcmNlbnR2YXIgPSBtZWFuKHBlcmNlbnRfdmFyaWF0aW9uKSwgCiAgICAgICAgICAgICN0cnlpbmcgYSBkaWZmIGNhbGMganVzdCB0byBzaG93IGl0cyB0aGUgc2FtZQogICAgICAgICAgICBwZXJjZW50X3ZhcmlhdGlvbiA9IDEwMCooc3VtKG51bWJlcl9hZG1pc3Npb25zKS1zdW0oYXZlcmFnZTIwMTgyMDE5KSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvc3VtKGF2ZXJhZ2UyMDE4MjAxOSkpIApgYGAKYGBge3J9CndlZWtseV9hZG1pc3Npb25zX3NwZWMgJT4lIAogIGZpbHRlcihzcGVjaWFsaXR5ICE9IkFsbCIpICU+JSAKICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0iQWxsIikgJT4lIAogIGZpbHRlcihoYl9uYW1lID09ICJBbGwgU2NvdGxhbmQiKSAlPiUgCiAgZ3JvdXBfYnkoc3BlY2lhbGl0eSkgJT4lIAogIHN1bW1hcmlzZShjb3VudF9iYWRfZGF5cyA9IHN1bShhYm92ZV90aHJlc2gpLCAKICAgICAgICAgICAgY291bnRfZGF5cyA9IG4oKSo3LCAKICAgICAgICAgICAgcGNudF9iYWRfZGF5cyA9IDEwMCooc3VtKGFib3ZlX3RocmVzaCkvKG4oKSo3KSksIAogICAgICAgICAgICBtZWFuX3BlcmNlbnR2YXIgPW1lYW4ocGVyY2VudF92YXJpYXRpb24pKSAlPiUgCiAgZ2dwbG90KCkgKwogIGFlcyh4PXNwZWNpYWxpdHksIHk9cGNudF9iYWRfZGF5cykgKwogIGdlb21fY29sKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpIApgYGAKCgoKYGBge3J9CndlZWtseV9hZG1pc3Npb25zX2RlbW9nICU+JSAKICBmaWx0ZXIoc2V4PT0iQWxsIikgJT4lIAogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSJBbGwiKSAlPiUgCiAgZmlsdGVyKGhiX25hbWU9PSJBbGwgU2NvdGxhbmQiKSAlPiUgCiAgZ3JvdXBfYnkoYWdlX2dyb3VwKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50X2JhZF9kYXlzID0gc3VtKGFib3ZlX3RocmVzaCksIAogICAgICAgICAgICBjb3VudF9kYXlzID0gbigpKjcsIAogICAgICAgICAgICBwY250X2JhZF9kYXlzID0gMTAwKihzdW0oYWJvdmVfdGhyZXNoKS8obigpKjcpKSwgCiAgICAgICAgICAgIG1lYW5fcGVyY2VudHZhciA9bWVhbihwZXJjZW50X3ZhcmlhdGlvbikpICU+JSAKICBnZ3Bsb3QoKSArCiAgYWVzKHg9YWdlX2dyb3VwLCB5PXBjbnRfYmFkX2RheXMpICsKICBnZW9tX2NvbCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSAKYGBgCgpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfZGVtb2cgJT4lIAogIGZpbHRlcihhZ2VfZ3JvdXA9PSJBbGwgYWdlcyIpICU+JSAKICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0iQWxsIikgJT4lIAogIGZpbHRlcihoYl9uYW1lPT0iQWxsIFNjb3RsYW5kIikgJT4lIAogIGdyb3VwX2J5KHNleCkgJT4lIAogIHN1bW1hcmlzZShjb3VudF9iYWRfZGF5cyA9IHN1bShhYm92ZV90aHJlc2gpLCAKICAgICAgICAgICAgY291bnRfZGF5cyA9IG4oKSo3LCAKICAgICAgICAgICAgcGNudF9iYWRfZGF5cyA9IDEwMCooc3VtKGFib3ZlX3RocmVzaCkvKG4oKSo3KSksIAogICAgICAgICAgICBtZWFuX3BlcmNlbnR2YXIgPW1lYW4ocGVyY2VudF92YXJpYXRpb24pKSAlPiUgCiAgZ2dwbG90KCkgKwogIGFlcyh4PXNleCwgeT1wY250X2JhZF9kYXlzKSArCiAgZ2VvbV9jb2woKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkKYGBgCm5vIG9idmlvdXMgZGlmZmVyZW5jZSBiZXR3ZWVuIHNleGVzCgpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfZGVwICU+JSAKICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0iQWxsIikgJT4lIAogIGZpbHRlcihoYl9uYW1lPT0iQWxsIFNjb3RsYW5kIikgJT4lIAogIGdyb3VwX2J5KHNpbWRfcXVpbnRpbGUsIHllYXIpICU+JSAKICBzdW1tYXJpc2UoY291bnRfYmFkX2RheXMgPSBzdW0oYWJvdmVfdGhyZXNoKSwgCiAgICAgICAgICAgIGNvdW50X2RheXMgPSBuKCkqNywgCiAgICAgICAgICAgIHBjbnRfYmFkX2RheXMgPSAxMDAqKHN1bShhYm92ZV90aHJlc2gpLyhuKCkqNykpLCAKICAgICAgICAgICAgbWVhbl9wZXJjZW50dmFyID1tZWFuKHBlcmNlbnRfdmFyaWF0aW9uKSkgJT4lIAogIGdncGxvdCgpICsKICBhZXMoeD1zaW1kX3F1aW50aWxlLCB5PXBjbnRfYmFkX2RheXMpICsKICBnZW9tX2NvbCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArIAogIGZhY2V0X2dyaWQofnllYXIpCmBgYA==